#ifndef RAYCASTER_H
#define RAYCASTER_H

//#define XMAX 4
//#define YMAX 4
//#define ZMAX 4

//#define XMAX 260
//#define YMAX 260
//#define ZMAX 260

//head32X32X32.raw
//#define XMAX 258
//#define YMAX 258
//#define ZMAX 258

//#define XMAX 32
//#define YMAX 32
//#define ZMAX 32

#define XMAX 256
#define YMAX 256
#define ZMAX 256

//#define XMAX 360
//#define YMAX 256
//#define ZMAX 166

//#define XMAX 128
//#define YMAX 128
//#define ZMAX 128

#define MAXVOLUMETEXTURE 3






#include "include\glew.h"
#include "Program.h"
#include "framebufferObject.h"
#include <math.h>
#include <iostream>

// raycasting status
typedef struct
{
	bool phongshading;
	float isovalue;
	float stepsize;

}raycasterstatus;


class RayCaster
{
public:
	RayCaster(int w, int h);
	~RayCaster();


	bool LoadVolume(char*); // load volume-> create texture -> release data
	bool LoadGradientVolume(char*);
	bool LoadLowRes(char*);

	void InitializeRayCaster(); // create buffer, create program for raycasting

	void Render();
	void ImageSpaceAdaptiveRender(float);
	void RenderDemo();
	void ImageSpaceAdaptiveRender2();

	void setRotation(float x, float y);
	void setRotationMatrix(float[]);
	void setTranslation(float[]);
	void setTransferFunctionTexture(GLuint tex);

	//set raycasting status
	void setStepSize(float steps){stepsize = steps;}
	void setIsoValue(float isovalue){iso_value = isovalue;}
	//TODO
	void setRaycasterStatus( raycasterstatus status);

	double* getHistogram(){return histogram;}
	void updateHiresBoundary();

	void saveCoreStatus(char* filename); //TF, view matrix

private:
	void _createProgram();
	void _drawRenderTarget(int o_x, int o_y, int x, int y, GLuint tex);
	//program
	Program vertexonlyprog, raycastprog, pass2prog, raycastprog2, raycastprog3;
	//textures
	GLuint m_volumeTexture[MAXVOLUMETEXTURE];
	GLuint m_lowResVolume, m_lowResVolumeMixed;
	GLuint m_backface, m_raycast, m_sbackface, m_sraycast;

	//fbo
	FramebufferObject *fbo1, *fbo2, *sfbo1, *sfbo2;

	//histogram
	double histogram[256];
	GLuint Lut;

	//state variables
	float m_x, m_y, m_z;
	int m_Width,m_Height;
	float stepsize;
	float iso_value;

    float m_rotationY;
	float m_rotationX;
	float m_rotationMatrix[16];
	float m_pos[3];

	//temp
	unsigned char* _hiresVol,* _lowresVol;
};



#endif